<template>
  <div class="app-container">
    <el-container>
      <!-- 左侧树 -->
      <el-aside width="580px">
        <div class="filter-container query">
          <el-input v-model="filterText" placeholder="输入关键字进行过滤" style="width:200px;padding-right:10px;" />
          <el-button class="filter-item" style="margin-bottom: 1px !important;" type="primary" size="mini" icon="el-icon-search" @click="refreshTree">
            刷新
          </el-button>
          <el-button class="filter-item" style="margin-bottom: 1px !important;" type="info" size="mini" icon="el-icon-refresh" @click="resetTree">
            重置
          </el-button>
        </div>
        <el-tree
          ref="tree"
          :props="treeProps"
          :indent="16"
          node-key="id"
          :render-after-expand="true"
          :highlight-current="true"
          :check-on-click-node="true"
          :expand-on-click-node="false"
          :filter-node-method="filterNode"
          :lazy="true"
          :load="loadSubData"
          @node-click="handleNodeClick"
        />
      </el-aside>
      <el-main style="padding-top: 10px;">
        <div class="filter-container">
          <el-button v-if="viewTemp.id !== null" type="success" size="mini" @click="handleAddSub(viewTemp)">
            新增下级
          </el-button>
          <el-button v-if="viewTemp.pId !== null" type="success" size="mini" @click="handleAddSibling(viewTemp)">
            新增同级
          </el-button>
          <el-button v-if="viewTemp.id !== null && viewTemp.id !== 0" type="warning" size="mini" @click="handleUpdate(viewTemp)">
            编辑
          </el-button>
          <el-button v-if="viewTemp.id !== null && viewTemp.id !== 0 && viewTemp.isLeaf" size="mini" type="danger" @click="handleDelete(viewTemp)">
            删除
          </el-button>
        </div>
        <el-form :model="viewTemp" :disabled="true" label-position="right" label-width="150px" style="width: 500px; margin-left:50px;">
          <el-form-item label="资源ID" prop="id" style="display:none">
            <el-input v-model="viewTemp.id" />
          </el-form-item>
          <el-form-item label="资源名称" prop="resName">
            <el-input v-model="viewTemp.resName" />
          </el-form-item>
          <el-form-item label="资源前端名称" prop="resFname">
            <el-input v-model="viewTemp.resFname" />
          </el-form-item>
          <el-form-item label="资源类型" prop="resType">
            <el-select v-model="viewTemp.resType" class="filter-item">
              <el-option v-for="item in resTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="上级资源名称" prop="pName">
            <el-input v-model="viewTemp.pName" />
          </el-form-item>
          <el-form-item label="上级资源编号" prop="pId" style="display:none">
            <el-input v-model="viewTemp.pId" />
          </el-form-item>
          <el-form-item label="资源顺序" prop="resSeq">
            <el-input-number v-model="viewTemp.resSeq" :min="0" :max="99999999" :precision="0" :controls="false" />
          </el-form-item>
          <el-form-item label="资源URI" prop="resUri">
            <el-input v-model="viewTemp.resUri" />
          </el-form-item>
          <el-form-item label="资源前端视图路径" prop="resViewPath">
            <el-input v-model="viewTemp.resViewPath" />
          </el-form-item>
          <el-form-item label="资源图标（SVG）" prop="resIcon">
            <el-input v-model="viewTemp.resIcon" />
          </el-form-item>
          <el-form-item label="资源描述" prop="resDesc">
            <el-input v-model="viewTemp.resDesc" />
          </el-form-item>
          <el-form-item label="启用标记" prop="enableFlag">
            <el-select v-model="viewTemp.enableFlag" class="filter-item">
              <el-option v-for="item in enableFlagOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-form>
      </el-main>
    </el-container>

    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormVisible"
      top="1vh"
      width="550px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      center
    >
      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="120px" class="form-center">
        <el-form-item label="资源名称" prop="resName">
          <el-input v-model="temp.resName" maxlength="64" />
        </el-form-item>
        <el-form-item label="资源类型" prop="resType">
          <el-select v-model="temp.resType" class="filter-item">
            <el-option v-for="item in resTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="上级资源编号" prop="pId" style="display:none">
          <el-input v-model="temp.pId" :disabled="true" />
        </el-form-item>
        <el-form-item label="上级资源名称" prop="pName">
          <el-input v-model="temp.pName" :disabled="true" />
        </el-form-item>
        <el-form-item label="资源顺序" prop="resSeq">
          <el-input-number v-model="temp.resSeq" :min="0" :max="99999999" :precision="0" :controls="false" />
        </el-form-item>
        <el-form-item label="资源URI" prop="resUri">
          <el-input v-model="temp.resUri" maxlength="128" />
        </el-form-item>
        <el-form-item label="资源前端名称" prop="resFname">
          <el-input v-model="temp.resFname" maxlength="128" />
        </el-form-item>
        <el-form-item label="资源前端视图路径" prop="resViewPath">
          <el-input v-model="temp.resViewPath" maxlength="128" />
        </el-form-item>
        <el-form-item label="资源图标（SVG）" prop="resIcon">
          <el-input v-model="temp.resIcon" maxlength="64" />
        </el-form-item>
        <el-form-item label="资源描述" prop="resDesc">
          <el-input v-model="temp.resDesc" maxlength="128" />
        </el-form-item>
        <el-form-item label="启用标记" prop="enableFlag">
          <el-select v-model="temp.enableFlag" class="filter-item">
            <el-option v-for="item in enableFlagOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData(false):updateData()">
          保存&退出
        </el-button>
        <el-button v-if="dialogStatus==='create'" type="success" @click="createData(true)">
          保存&继续
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { fetchList, createAuthResource, updateAuthResource, deleteAuthResource } from '@/api/base/auth/authResource'
import { setOptionData } from '@/utils/dict'

export default {
  name: 'AuthResource',
  data() {
    return {
      treeProps: {
        label: 'resName',
        isLeaf: 'leaf'
      },
      isSaveAndContinue: false,
      enableFlagOptions: [],
      resTypeOptions: [],
      dataLoading: false,
      viewTemp: {
        id: null,
        resName: '',
        resFname: '',
        resType: '',
        pId: null,
        resSeq: null,
        resUri: '',
        resViewPath: '',
        resIcon: '',
        resDesc: '',
        enableFlag: '',
        createAt: '',
        createBy: '',
        updateAt: '',
        updateBy: ''
      },
      temp: {
        id: '',
        resName: '',
        resFname: '',
        resType: '',
        pId: '',
        resSeq: null,
        resUri: '',
        resViewPath: '',
        resIcon: '',
        resDesc: '',
        enableFlag: 'Y',
        createAt: '',
        createBy: '',
        updateAt: '',
        updateBy: ''
      },
      filterText: '',
      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        update: '编辑资源信息',
        create: '新增资源信息'
      },
      rules: {
        resName: [{ required: true, message: '资源名称不能为空', trigger: 'change' }],
        resType: [{ required: true, message: '资源类型不能为空', trigger: 'change' }],
        pId: [{ required: true, message: '上级资源ID不能为空', trigger: 'change' }],
        resSeq: [{ required: true, message: '资源序号不能为空', trigger: 'change' },
          { type: 'number', message: '资源序号必须为整数', trigger: 'change' }],
        resUri: [{ max: 128, message: '资源URI不能大于128个字符', trigger: 'change' }],
        enableFlag: [{ required: true, message: '启用标记不能为空', trigger: 'change' }]
      }
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    this.initDictInfos()
  },
  methods: {
    initDictInfos() { // 初始化数据字典
      // 加载下拉数据
      const optionsMap = new Map()
      optionsMap.set('ENABLE_FLAG', this.enableFlagOptions)
      optionsMap.set('BASE_RESOURCE_TYPE', this.resTypeOptions)
      setOptionData(optionsMap)
    },
    loadSubData(node, resolve) {
      if (node.level === 0) {
        return resolve([{
          id: 0,
          resName: '资源信息',
          resFname: '',
          resType: '',
          pId: null,
          resSeq: null,
          resUri: '',
          resViewPath: '',
          resIcon: '',
          resDesc: '',
          enableFlag: '',
          leaf: false,
          children: []
        }])
      } else {
        fetchList(node.data.id).then(response => {
          resolve(response.data)
        })
      }
    },
    handleNodeClick(data, node, other) {
      this.viewTemp = Object.assign({}, data)
      this.viewTemp.isLeaf = node.isLeaf
      this.viewTemp.pName = node.parent && node.parent.data ? node.parent.data.resName : ''
    },
    filterNode(value, data, node) {
      if (!value) {
        return true
      }
      return (data.resName.indexOf(value) !== -1)
    },
    refreshTree() {
      const pNode = this.$refs.tree.getNode(0)
      var theChildren = pNode.childNodes
      theChildren.splice(0, theChildren.length)
      pNode.loaded = false
      pNode.expanded = false
    },
    resetTree() {
      this.filterText = ''
      this.refreshTree()
    },
    resetTemp() {
      this.temp = {
        id: '',
        resName: '',
        resFname: '',
        resType: '',
        pId: '',
        resSeq: null,
        resUri: '',
        resViewPath: '',
        resIcon: '',
        resDesc: '',
        enableFlag: 'Y',
        createAt: '',
        createBy: '',
        updateAt: '',
        updateBy: ''
      }
    },
    resetViewTemp() {
      this.viewTemp = {
        id: '',
        resName: '',
        resFname: '',
        resType: '',
        pId: '',
        resSeq: null,
        resUri: '',
        resViewPath: '',
        resIcon: '',
        resDesc: '',
        enableFlag: '',
        createAt: '',
        createBy: '',
        updateAt: '',
        updateBy: ''
      }
    },
    handleAddSub(row) {
      this.resetTemp()
      this.temp.pId = row.id
      this.temp.pName = row.resName
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    handleAddSibling(row) {
      this.resetTemp()
      this.temp.pId = row.pId
      this.temp.pName = row.pName
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    createData(isSaveAndContinue) {
      this.isSaveAndContinue = isSaveAndContinue
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          createAuthResource(this.temp).then((response) => {
            response.data.leaf = true
            const data = response.data
            const pNode = this.$refs.tree.getNode(this.temp.pId)
            if (pNode) {
              this.insertNodeBySeq(data, pNode)
              pNode.isLeaf = false
              pNode.loaded = true
            }
            this.$message({
              message: '资源数据保存处理成功！',
              type: 'success'
            })

            if (this.isSaveAndContinue) {
              this.temp.id = null
              this.temp.resName = ''
              this.temp.resSeq = this.temp.resSeq + 1
              this.temp.resUri = ''
              this.temp.resDesc = ''
              this.temp.resFname = ''
              this.temp.resViewPath = ''
              this.temp.resIcon = ''
              this.$nextTick(() => {
                this.$refs['dataForm'].clearValidate()
              })
            } else {
              this.dialogFormVisible = false
            }
          })
        }
      })
    },
    insertNodeBySeq(data, pNode) {
      // 遍历childNodes，确定新创建的子节点要插入哪个位置
      var childNodes = pNode.childNodes
      var hadCreateNode = false
      for (var i = 0; i < childNodes.length; i++) {
        var childNode = childNodes[i]
        if (childNode.data.resSeq === data.resSeq) {
          if (childNode.data.id <= data.id) {
            this.$refs.tree.insertAfter(data, childNode)
            hadCreateNode = true
            break
          } else {
            this.$refs.tree.insertBefore(data, childNode)
            hadCreateNode = true
            break
          }
        } else if (childNode.data.resSeq > data.resSeq) {
          this.$refs.tree.insertBefore(data, childNode)
          hadCreateNode = true
          break
        }
      }
      if (!hadCreateNode) { // 如果该parentNode无子节点，或者resSeq比children的都要大
        this.$refs.tree.append(data, pNode)
      }
    },
    handleUpdate(row) {
      this.temp = Object.assign({}, row) // copy obj
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    updateData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          updateAuthResource(this.temp).then((response) => {
            const node = this.$refs.tree.getNode(this.temp.id)
            if (node) {
              if (node.data.resSeq === this.temp.resSeq) { // 节点resSeq无变化
                node.data.id = this.temp.id
                node.data.resName = this.temp.resName
                node.data.resFname = this.temp.resFname
                node.data.resType = this.temp.resType
                node.data.pId = this.temp.pId
                node.data.resSeq = this.temp.resSeq
                node.data.resUri = this.temp.resUri
                node.data.resViewPath = this.temp.resViewPath
                node.data.resIcon = this.temp.resIcon
                node.data.resDesc = this.temp.resDesc
                node.data.enableFlag = this.temp.enableFlag
              } else {
                // 如果resSeq有修改。先remove再重新insert，实现排序插入
                const pNode = this.$refs.tree.getNode(this.temp.pId)
                this.$refs.tree.remove(node)
                this.insertNodeBySeq(this.temp, pNode)
              }
            }
            if (this.viewTemp.id === this.temp.id) {
              this.viewTemp.resName = this.temp.resName
              this.viewTemp.resFname = this.temp.resFname
              this.viewTemp.resType = this.temp.resType
              this.viewTemp.pId = this.temp.pId
              this.viewTemp.resSeq = this.temp.resSeq
              this.viewTemp.resUri = this.temp.resUri
              this.viewTemp.resViewPath = this.temp.resViewPath
              this.viewTemp.resIcon = this.temp.resIcon
              this.viewTemp.resDesc = this.temp.resDesc
              this.viewTemp.enableFlag = this.temp.enableFlag
            }
            this.dialogFormVisible = false
            this.$message({
              message: '资源信息更新成功！',
              type: 'success'
            })
          })
        }
      })
    },
    handleDelete(row) {
      this.$msgbox({
        type: 'warning',
        title: '确认信息',
        message: '此操作将删除资源数据[' + row.resUri + '], 是否继续?',
        showCancelButton: true,
        showClose: false,
        closeOnPressEscape: false,
        closeOnClickModal: false,
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            deleteAuthResource(row.id).then((response) => {
              const node = this.$refs.tree.getNode(row.id)
              if (node) {
                this.$refs.tree.remove(node)
              }
              this.resetViewTemp()
              this.$message({
                message: '资源数据删除处理成功!',
                type: 'success'
              })
              done()
              instance.confirmButtonLoading = false
            }, (response) => {
              done()
              instance.confirmButtonLoading = false
            })
          } else {
            done()
          }
        }
      }).catch(() => {})
    }
  }
}
</script>
